﻿using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Windows.System;
using Windows.UI;
using Windows.UI.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;
using Windows8Accelerator.Core.Xaml.Controls;
using Windows8Accelerator.Core.Xaml.Controls.RichText;
using Windows8Accelerator.Core.Xaml.Converters;
using Windows8Accelerator.Core.Xaml.Helpers;
using Windows8Accelerator.Core.Xaml.Html;

namespace Windows8Accelerator.Core.Xaml.Controls.RichText
{
    public class RichTextBlockHtmlLoader
    {
        public event EventHandler<HyperlinkClickEventArgs> HyperlinkClick;
        protected void OnHyperlinkClick(HyperlinkClickEventArgs e)
        {
            if (HyperlinkClick != null)
                HyperlinkClick(this, e);
        }

        public event EventHandler<ImageClickEventArgs> ImageClick;
        protected void OnImageClick(ImageClickEventArgs e)
        {
            if (ImageClick != null)
                ImageClick(this, e);
        }

        public Task LoadAsync(RichTextBlock richTextBlock, string html)
        {
            Load(richTextBlock, html);
            return Task.Run(() => { });
        }

        public void Load(RichTextBlock richTextBlock, string html)
        {
            var htmlDocument = new HtmlDocument();
            htmlDocument.LoadHtml(html);

            RichTextFactory.ClearPrevious(richTextBlock);

            var superNode = ConvertToSuperHtmlNode(htmlDocument.DocumentNode);
            var visitor = SuperHtmlNodeVisitor.CreateVisitor(superNode, null);
            visitor.Parent = richTextBlock;
            visitor.State.DefaultTextFormat = SuperTextFormatHelper.GetRichTextBlockFormat(richTextBlock);
            visitor.State.OnHyperlinkClick = OnHyperlinkClick;
            visitor.State.OnImageClick = OnImageClick;
            visitor.Visit();

            //var html1 = ToHtml(richTextBlock);
        }

        public void Load(Paragraph paragraph, string html, RichTextBlock richTextBlock)
        {
            var htmlDocument = new HtmlDocument();
            htmlDocument.LoadHtml(html);

            paragraph.Inlines.Clear();

            var superNode = ConvertToSuperHtmlNode(htmlDocument.DocumentNode);
            var visitor = SuperHtmlNodeVisitor.CreateVisitor(superNode, null);
            visitor.Parent = paragraph;
            visitor.State.DefaultTextFormat = SuperTextFormatHelper.GetRichTextBlockFormat(richTextBlock);
            visitor.State.OnHyperlinkClick = OnHyperlinkClick;
            visitor.State.OnImageClick = OnImageClick;
            visitor.Visit();
        }
        private async Task<string> ToHtmlAsync(RichTextBlock richTextBlock)
        {
            return await Task.Run<string>(() =>
            {
                return ToHtml(richTextBlock);
            });
        }

        private string ToHtml(RichTextBlock richTextBlock)
        {
            var sb = new StringBuilder();
            foreach (Paragraph block in richTextBlock.Blocks)
            {
                VisitBlock(block, sb);
            }
            return sb.ToString();
        }

        private void VisitBlock(Paragraph block, StringBuilder sb)
        {
            foreach (var item in block.Inlines)
            {
                sb.Append("<div>");
                VisitInline(item, sb);
                sb.Append("</div>");
            }
        }

        private void VisitInline(Inline item, StringBuilder sb)
        {
            if (item is Span)
            {
                sb.Append("<span>");
                foreach (var item1 in ((Span)item).Inlines)
                {
                    VisitInline(item1, sb);
                }
                sb.Append("</span>");
            }
            else if (item is Run)
            {
                sb.Append(((Run)item).Text);
            }
            else if (item is LineBreak)
            {
                sb.Append("<br/>");
            }
            else if (item is InlineUIContainer)
            {
                var inlineUIContainer = item as InlineUIContainer;
                if (inlineUIContainer.Child is HyperlinkButton)
                    sb.Append("<a />");
                else if (inlineUIContainer.Child is Image)
                    sb.Append("<img />");
            }
        }

        public bool FlattenContainers { get; set; }

        private SuperHtmlNode ConvertToSuperHtmlNode(HtmlNode htmlNode)
        {
            return new SuperHtmlNode()
            {
                TagName = htmlNode.Name.ToLower(),
                IsText = htmlNode.NodeType == HtmlNodeType.Text,
                Text = htmlNode.InnerText,
                GetChildNodes = () =>
                {
                    return htmlNode.ChildNodes.Where((n)=>n.NodeType != HtmlNodeType.Comment).Select((n) => ConvertToSuperHtmlNode(n));
                },
                GetAttributes = ()=>{
                    return htmlNode.Attributes.Select((a)=> new Tuple<string, string>(a.Name, a.Value));               
                },
            };
        }
    }


}
